package br.ufrn.geologia.ggemma.model.service;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.jspresso.framework.application.backend.persistence.hibernate.HibernateBackendController;
import org.jspresso.framework.application.backend.session.EMergeMode;
import org.jspresso.framework.model.component.service.EmptyLifecycleInterceptor;
import org.jspresso.framework.model.entity.IEntityFactory;
import org.jspresso.framework.model.entity.IEntityLifecycleHandler;
import org.jspresso.framework.security.UserPrincipal;

import br.ufrn.geologia.ggemma.model.Role;
import br.ufrn.geologia.ggemma.model.User;

public class UserLifecycleInterceptor extends EmptyLifecycleInterceptor<User> {

	@Override
	public boolean onPersist(User user, IEntityFactory entityFactory, UserPrincipal principal,
			IEntityLifecycleHandler entityLifecycleHandler) {
		initilializeRolesFor(user, entityLifecycleHandler);
		return super.onPersist(user, entityFactory, principal, entityLifecycleHandler);
	}

	@Override
	public boolean onUpdate(User user, IEntityFactory entityFactory, UserPrincipal principal,
			IEntityLifecycleHandler entityLifecycleHandler) {
		initilializeRolesFor(user, entityLifecycleHandler);
		return super.onUpdate(user, entityFactory, principal, entityLifecycleHandler);
	}
	
	@Override
	public boolean onCreate(User user, IEntityFactory entityFactory, UserPrincipal principal,
			IEntityLifecycleHandler entityLifecycleHandler) {
		initilializeRolesFor(user, entityLifecycleHandler);
		return super.onCreate(user, entityFactory, principal, entityLifecycleHandler);
	}
	
	private void initilializeRolesFor(User user, IEntityLifecycleHandler entityLifecycleHandler) {
		if (user.getRoles().isEmpty()) {
			HibernateBackendController controller = (HibernateBackendController) entityLifecycleHandler;
			DetachedCriteria userCriteria = DetachedCriteria.forClass(Role.class);
			userCriteria.add(Restrictions.eq("roleId", "USER"));
			List<Role> roles = controller.findByCriteria(userCriteria, EMergeMode.MERGE_KEEP, Role.class);
			if (roles == null || roles.isEmpty()) {
				throw new RuntimeException(
						"The role USER must be present in the database. Has it been correctly initialized?");
			} else {
				user.addToRoles(roles.get(0));
			}
		}
	}
}
